﻿using System.Web.Mvc;
using Risk.Model;
using Risk.Services;
using Site.Models;

namespace Site.Controllers
{
    public class GameController : Controller
    {
        //
        // GET: /Game/{gameId}/{playerId}/
        //
        public ActionResult Index(int gameId, int playerId)
        {
            return View();
        }

        /// <summary>
        /// Method to load a game
        /// </summary>
        /// <param name="gameId">The id of the game</param>
        /// <param name="playerId">The id of this player</param>
        /// <returns>a nameless object with a GameDTO and the playerId</returns>
        public JsonResult LoadGame(int gameId, int playerId)
        {
            //todo check of juiste persoon wel ingelogd is
            var game = new GameDTO(gameId);
            return Json(new {
                game, playerId
            }, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// Method to add a single troop to a region
        /// </summary>
        /// <param name="gameId">The id of the game</param>
        /// <param name="playerId">The id of this player</param>
        /// <param name="region">The id of the region to add a troop to</param>
        /// <returns>true if the troop was successfully added</returns>
        public JsonResult AddTroop(int gameId, int playerId, string region)
        {
            Game game = DatabaseManager.LoadGame(gameId);
            PlayerState playerState = game.Players[playerId].PlayerState;
            var playerArmy = game.Armies[playerId];
            if (playerState == PlayerState.Initial)
            {
                if (playerArmy.Reserve == 0)
                    return Json(false, JsonRequestBehavior.AllowGet);
                bool result = playerArmy.PlaceInitialTroops(playerId, region);
                if (result == false)
                    return Json(false, JsonRequestBehavior.AllowGet);
            }
            else if (playerState == PlayerState.Reinforcing)
            {
                if (!playerArmy.AddTroop(region))
                {
                    return Json(false, JsonRequestBehavior.AllowGet);
                }
            }
            DatabaseManager.SetArmyReserve(playerArmy.Reserve, playerArmy.Id);
            var targetTroopGroup = playerArmy.TroopGroup.Find(t => t.Region.Id == region);
            DatabaseManager.SetTroopCount(targetTroopGroup.TroopSize, targetTroopGroup.Id);
            return Json(true, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// Method to attack a region. The number of defending dice is always the maximum amount.
        /// </summary>
        /// <param name="gameId">The id of the game</param>
        /// <param name="playerId">The id of this player</param>
        /// <param name="from">The id of the region to attack from</param>
        /// <param name="to">The id of the region to attack</param>
        /// <param name="numberOfDice">The number of attacking dice</param>
        /// <returns>a ThrowDTO object</returns>
        public JsonResult Attack(int gameId, int playerId, string from, string to, int numberOfDice)
        {
            var game = DatabaseManager.LoadGame(gameId);
            var throwResult = game.Attack(playerId, from, to, numberOfDice);
            var result = new ThrowDTO(throwResult);
            var fromTroop = game.GetTroopGroup(from);
            var toTroop = game.GetTroopGroup(to);
            DatabaseManager.SetTroopCount(fromTroop.TroopSize, fromTroop.Id);
            DatabaseManager.SetTroopCount(toTroop.TroopSize, toTroop.Id);
            // zet nieuwe eigenaar als speler het gebied heeft veroverd
            if(result.Victory)
                DatabaseManager.SetTroopArmy(game.Armies[playerId].Id, toTroop.Id);
            // win => 1 verplaatsen & armyId
            return Json(result, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// Method to move men to a neighbouring region
        /// </summary>
        /// <param name="gameId">The id of the game</param>
        /// <param name="playerId">The id of this player</param>
        /// <param name="from">The id of the region to move from</param>
        /// <param name="to">The id of the region to move to</param>
        /// <param name="number">The number of men to move</param>
        /// <returns>true if the move was successfully</returns>
        public JsonResult Move(int gameId, int playerId, string from, string to, int number)
        {
            
            var game = DatabaseManager.LoadGame(gameId);


            var result = game.Move(playerId, from, to, number);
            if(result == false)
                return Json(false, JsonRequestBehavior.AllowGet);
            var fromTroop = game.GetTroopGroup(from);
            var toTroop = game.GetTroopGroup(to);
            DatabaseManager.SetTroopCount(fromTroop.TroopSize, fromTroop.Id);
            DatabaseManager.SetTroopCount(toTroop.TroopSize, toTroop.Id);

            return Json(true, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// Method to end the current stage
        /// </summary>
        /// <param name="gameId">The id of the game</param>
        /// <param name="playerId">The id of this player</param>
        /// <returns>true if the stage was successfully closed</returns>
        public JsonResult StageDone(int gameId, int playerId)
        {

            Game game = DatabaseManager.LoadGame(gameId);
            // als er spelers met state = 1 zijn, gewoon state op 0 zetten
            // als deze speler state 1  had dan krijgt speler met risk index 0 state 0
            bool result = game.EndStage(playerId);
            if (result == false)
                return Json(false, JsonRequestBehavior.AllowGet);
            //update playerStates
            foreach (Player p in game.Players)
                DatabaseManager.SetPlayerState((int) p.PlayerState, p.Id);
            foreach (Army a in game.Armies)
            {
                DatabaseManager.SetArmyReserve(a.Reserve, a.Id);
                DatabaseManager.SetArmyBonus(a.Bonus, a.Id);
            }

            if (game.GameOver())
            {
                DatabaseManager.EndGame(gameId, game.Winner().Name);
                foreach (Player p in game.Players)
                    DatabaseManager.SetPlayerState((int) PlayerState.Waiting, p.Id);
            }
            return Json(true, JsonRequestBehavior.AllowGet);
        }
    }
}
